package com.tzsafe.nfcdemo

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Dialog
import android.app.PendingIntent
import android.bluetooth.BluetoothManager
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.AnimationDrawable
import android.nfc.*
import android.nfc.NdefRecord
import android.nfc.tech.MifareUltralight
import android.nfc.tech.Ndef
import android.os.Build
import android.os.Bundle
import android.text.Spannable
import android.text.SpannableString
import android.text.style.ForegroundColorSpan
import android.util.Log
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.View.OnClickListener
import android.widget.ImageView
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import com.google.gson.Gson
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import com.hjq.toast.ToastUtils
import com.hjy.bluetooth.HBluetooth
import com.hjy.bluetooth.entity.BluetoothDevice
import com.inuker.bluetooth.library.Code.REQUEST_SUCCESS
import com.inuker.bluetooth.library.Constants.STATUS_CONNECTED
import com.inuker.bluetooth.library.Constants.STATUS_DISCONNECTED
import com.inuker.bluetooth.library.connect.listener.BleConnectStatusListener
import com.inuker.bluetooth.library.connect.options.BleConnectOptions
import com.inuker.bluetooth.library.connect.response.BleNotifyResponse
import com.kongzue.dialogx.dialogs.MessageDialog
import com.kongzue.dialogx.dialogs.WaitDialog
import com.kongzue.dialogx.interfaces.OnBackPressedListener
import com.kongzue.dialogx.interfaces.OnDialogButtonClickListener
import com.tzsafe.nfcdemo.databinding.ActivityNfcMainBinding
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.IOException
import java.util.*
import kotlin.experimental.xor

/**
 * 主界面
 */
class NFCMainActivity : AppCompatActivity(), OnClickListener {
    private val organizationInfoLauncher = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { result: ActivityResult ->
        if (result.resultCode == Activity.RESULT_OK) {
            result.data?.let { intent ->
                val receivedTitle  = intent.getStringExtra("title") ?: ""
                var systemCode = intent.getStringExtra("system_code") ?: ""

                if ((receivedTitle  == userInfo.name) && (systemCode.isEmpty())) {
                    systemCode = userInfo.system_code
                }

                Log.d("MainActivity", "Received title: $receivedTitle , pwd:$systemCode")
                appendColoredText("【组织机构】：$receivedTitle ", TextColor.WHITE)
                appendColoredText("【系统编码】：$systemCode", TextColor.WHITE)

                val sharedPreferences = getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
                sharedPreferences.edit().putString("app_name", receivedTitle).apply()
                // 在下次启动时读取并应用
                val savedName = sharedPreferences.getString("app_name", null)
                savedName?.let { title = it }

                userInfo.name = receivedTitle
                userInfo.system_code = systemCode
                SharedPreferencesUtils.saveUserInfo(this, receivedTitle, systemCode)
            }
        }
    }

    companion object {
        //钥匙UUID
        val RX_SERVICE_UUID:    UUID = UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb")
        val TX_CHAR_UUID:       UUID = UUID.fromString("0000fff1-0000-1000-8000-00805f9b34fb") //写数据，从手机的角度
        val RX_CHAR_UUID:       UUID = UUID.fromString("0000fff2-0000-1000-8000-00805f9b34fb") //读数据
    }

    private var swipeDialog: Dialog? = null
    private var animationDrawable: AnimationDrawable? = null

    private var mMac: String? = ""
    private var mName: String? = ""
    private var mConnected = false
    private val mBleConnectStatusListener: BleConnectStatusListener =
        object : BleConnectStatusListener() {
            override fun onConnectStatusChanged(mac: String, status: Int) {
                if (status == STATUS_CONNECTED) {
                    appendColoredText("蓝牙连接成功: $mName --- $mMac", TextColor.WHITE)
                    mConnected = true
                    openNotify(mac, RX_SERVICE_UUID, RX_CHAR_UUID)
                    updateBluetoothIcon()
                } else if (status == STATUS_DISCONNECTED) {
                    appendColoredText("蓝牙连接断开", TextColor.RED)
                    mConnected = false
                    closeNotify(mac, RX_SERVICE_UUID, TX_CHAR_UUID)
                    updateBluetoothIcon()
                }
            }
        }
    private lateinit var mBind: ActivityNfcMainBinding
    private lateinit var userInfo: UserInfo  // 确保已初始化
    var mHBluetooth: HBluetooth? = null
    private var mNfcAdapter: NfcAdapter? = null
    private var mPendingIntent: PendingIntent? = null

    enum class TextColor(val value: Int) {
        GREEN(1),
        WHITE(2),
        RED(3)
    }

    sealed class NfcAction {
        data object InitNfc : NfcAction()
        data object FormatNfc : NfcAction()
    }

    private var nfcAction: NfcAction? = null
    private var msgData: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBind = ActivityNfcMainBinding.inflate(layoutInflater)
        setContentView(mBind.root)
        val manager: NfcManager = getSystemService(Context.NFC_SERVICE) as NfcManager
        checkPermission()
        checkBlueToothAdapter()



        if (NetCheckUtils.isNetworkAvailable()) {        //判断网络状况
            appendColoredText("网络正常", TextColor.WHITE)
        } else {
            appendColoredText("网络不可用", TextColor.WHITE)
        }

        // 加载用户信息
        userInfo = SharedPreferencesUtils.loadUserInfo(this)
        title = userInfo.name
        val sharedPreferences = getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
        sharedPreferences.edit().apply{
            putString("app_name", title.toString())
            apply()
        }

        // 在下次启动时读取并应用
        val savedName = sharedPreferences.getString("app_name", null)
        savedName?.let { title = it }

        try {
            mNfcAdapter = manager.defaultAdapter
            if (mNfcAdapter != null) {
                // 这里建议将处理NFC的子类的launchMode设置成singleTop模式，这样感应到标签时就会回调onNewIntent，而不会重复打开页面
                mPendingIntent =
                    PendingIntent.getActivity(
                        this,
                        0,
                        Intent(this, this::class.java),
                        PendingIntent.FLAG_IMMUTABLE
                    )
//                checkPermissions()
//                box = ObjectBox.boxStore.boxFor()

            } else {
                AlertDialog.Builder(this)
                    .setTitle("警告")
                    .setMessage("当前设备不支持NFC或NFC未打开")
                    .setPositiveButton("确认") { _, _ ->
                        finish()
                    }
                    .show()

            }
        } catch (e: IllegalStateException) {
            AlertDialog.Builder(this)
                .setTitle("警告")
                .setMessage("当前设备不支持NFC或NFC未打开")
                .setPositiveButton("确认") { _, _ ->
                    finish()
                }
                .show()

        }
        mBind.btnInitNFCCard.setOnClickListener(this)
        mBind.btnFormatNFC.setOnClickListener(this)
        mBind.clearTips.setOnClickListener(this)
        mBind.btnLockInit.setOnClickListener(this)
        mBind.btnLockSetDefault.setOnClickListener(this)
        mBind.btnCfgOrganization.setOnClickListener(this)

//        LiveDataEvent.connectBleDevice.observe(this, androidx.lifecycle.Observer {
//            if (LiveDataEvent.connectBleDevice.value?.connect == true) {
//                mMac = it.bluetoothDevice?.address
//                mName = it.bluetoothDevice?.name
//                connectDevice(LiveDataEvent.connectBleDevice.value!!.bluetoothDevice as BluetoothDevice)
//            }
//        })
        LiveDataEvent.connectBleDevice.observe(this) { event ->
            event?.takeIf { it.connect }?.let { validEvent ->
                mMac = validEvent.bluetoothDevice?.address
                mName = validEvent.bluetoothDevice?.name
                validEvent.bluetoothDevice?.let { device ->
                    connectDevice(device)
                }
            }
        }
    }

    private fun connectDevice(bluetoothDevice: BluetoothDevice?) {
        Log.e("测试", "连接设备    " + bluetoothDevice?.name)
        if (!mConnected) {
            lifecycleScope.launch {
                delay(300)
                val dialog = WaitDialog.show("连接中")
                dialog.onBackPressedListener = OnBackPressedListener {
                    dialog.doDismiss()
                    false
                }
                ClientManager.getClient()
                    .registerConnectStatusListener(mMac, mBleConnectStatusListener)
                val options = BleConnectOptions.Builder().setConnectRetry(1) // 连接如果失败重试3次
                    .setConnectTimeout(5000) // 连接超时5s
                    .setServiceDiscoverRetry(1) // 发现服务如果失败重试3次
                    .setServiceDiscoverTimeout(5000) // 发现服务超时5s
                    .build()

                ClientManager.getClient().connect(
                    mMac, options
                ) { code, _ ->
                    dialog.doDismiss()
                    if (code == REQUEST_SUCCESS) {
                        ToastUtils.show(bluetoothDevice?.name.toString() + "连接成功")
                        try {
                            Thread.sleep(200)
                        } catch (e: InterruptedException) {
                            e.printStackTrace()
                        }
                    } else {
                        ToastUtils.show(bluetoothDevice?.name.toString() + "连接失败")
                        Toast.makeText(
                            applicationContext, "连接失败,请重启蓝牙", Toast.LENGTH_SHORT
                        ).show()
                        ClientManager.getClient().disconnect(mMac)
                    }
                }
            }


        }

    }

    //打开notification通知
    private fun openNotify(mac: String, serviceUUID: UUID, characterUUID: UUID) {
        ClientManager.getClient()
            .notify(mac, serviceUUID, characterUUID, object : BleNotifyResponse {
                override fun onNotify(service: UUID, character: UUID, result: ByteArray) {
                    Log.e("返回数据", "返回数据 " + MyUtil.bytes2Hex(result))
                    Log.e("返回数据", "返回数据 " + String(result))
                    appendColoredText("收到数据:" + String(result), TextColor.GREEN)
                }

                override fun onResponse(code: Int) {
                    if (code == REQUEST_SUCCESS) {
                        ToastUtils.show("打开通知成功")
                        appendColoredText("打开通知成功", TextColor.GREEN)
                    } else {
                        ToastUtils.show("打开通知失败")
                    }
                }
            })
    }

    //关闭notify
    private fun closeNotify(mac: String, serviceUUID: UUID, characterUUID: UUID) {
        ClientManager.getClient()
            .unnotify(mac, serviceUUID, characterUUID) { code ->
                Log.e("unNotify", "unNotify  $code")
                if (code == REQUEST_SUCCESS) {
                    Log.e("unNotify", "REQUEST_SUCCESS")
                }
            }
    }

    private fun checkBlueToothAdapter() {
        val mAdapter = (getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager).adapter
        if (!mAdapter.isEnabled) {
            MessageDialog.show(
                "提示", "跳转到设置界面打开蓝牙？", "OK", "Cancel"
            ).apply {
                okButtonClickListener = OnDialogButtonClickListener { dialog, _ ->
                    ToastUtils.show("点击了ok")
                    dialog.dismiss()
                    true
                }
                cancelButtonClickListener = OnDialogButtonClickListener { dialog, _ ->
                    ToastUtils.show("点击了cancel")
                    dialog.dismiss()
                    true
                }
            }
        } else {
            Log.e("蓝牙", "蓝牙已启用")
        }
    }

    private fun checkPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            Log.e("高版本", "高版本")
//            .permission(Permission.READ_EXTERNAL_STORAGE)
//                .permission(Permission.WRITE_EXTERNAL_STORAGE)
            XXPermissions.with(this) // 申请单个权限
                .permission(Permission.BLUETOOTH_CONNECT).permission(Permission.BLUETOOTH_SCAN)
                .permission(Permission.MANAGE_EXTERNAL_STORAGE)
                .request(object : OnPermissionCallback {
                    override fun onGranted(permissions: List<String>, all: Boolean) {
                        if (all) {
                            mHBluetooth = HBluetooth.getInstance()

                            //请填写你自己设备的UUID
                            //低功耗蓝牙才需要如下配置BleConfig,经典蓝牙不需要new HBluetooth.BleConfig()
                            val bleConfig = HBluetooth.BleConfig()
                            bleConfig.withServiceUUID("6e400001-b5a3-f393-e0a9-e50e24dcca9e")
                                .withWriteCharacteristicUUID("6e400002-b5a3-f393-e0a9-e50e24dcca9e")
                                .withNotifyCharacteristicUUID("6e400003-b5a3-f393-e0a9-e50e24dcca9e")
                            mHBluetooth?.let {
                                it.enableBluetooth()
                                it.enableBluetooth().bleConfig = bleConfig
                            }
                        }
                    }

                    override fun onDenied(permissions: List<String>, never: Boolean) {
                        if (never) {
                            // 如果是被永久拒绝就跳转到应用权限系统设置页面
                            XXPermissions.startPermissionActivity(
                                this@NFCMainActivity, permissions
                            )
                        } else {
                            ToastUtils.show("请通过权限后再操作应用")
                        }
                    }
                })
        } else {
            Log.e("低版本", "低版本")
            XXPermissions.with(this) // 申请单个权限
                .permission(Permission.ACCESS_FINE_LOCATION) // 申请多个权限
                .permission(Permission.ACCESS_COARSE_LOCATION)
                .permission(Permission.READ_EXTERNAL_STORAGE)
                .permission(Permission.WRITE_EXTERNAL_STORAGE)
                .request(object : OnPermissionCallback {
                    override fun onGranted(permissions: List<String>, all: Boolean) {
                        if (all) {
                            mHBluetooth = HBluetooth.getInstance()
                            val bleConfig = HBluetooth.BleConfig()
                            bleConfig.withServiceUUID("6e400001-b5a3-f393-e0a9-e50e24dcca9e")
                                .withWriteCharacteristicUUID("6e400002-b5a3-f393-e0a9-e50e24dcca9e")
                                .withNotifyCharacteristicUUID("6e400003-b5a3-f393-e0a9-e50e24dcca9e")
                            mHBluetooth?.let {
                                it.enableBluetooth().bleConfig = bleConfig
                            }
                        }
                    }

                    override fun onDenied(permissions: List<String>, never: Boolean) {
                        if (never) {
                            ToastUtils.show("android12以下 被永久拒绝授权，请手动授予权限")
                            // 如果是被永久拒绝就跳转到应用权限系统设置页面
                            XXPermissions.startPermissionActivity(
                                this@NFCMainActivity, permissions
                            )
                        } else {
                            ToastUtils.show("请通过权限后再操作应用")
                        }
                    }
                })
        }
    }

    override fun onClick(v: View?) {
        when (v?.id) {
            R.id.btnInitNFCCard -> {
                nfcAction = NfcAction.InitNfc
                if (title == "NFC&amp;BLE") {
                    // 使用DialogX显示对话框
                    MessageDialog.show("提示", "请选择正确的机构名称")
                        .setCancelable(true) // 允许点击空白位置关闭对话框
                } else {
                    showNFCDialog()
                }
            }

            R.id.btnFormatNFC -> {
                nfcAction = NfcAction.FormatNfc
                showNFCDialog()
            }

            R.id.btnLockInit -> {           // {"InitLock":"1234&9IxB"}
                if(mConnected) {
                    data class InitString(val initLock: String)

                    val str = InitString("1234&" + userInfo.system_code.substring(0, 4))
                    val json = Gson().toJson(str)
                    appendColoredText("发送:" + json.replace("\\u0026", "&"), TextColor.WHITE)

                    ClientManager.getClient()
                        .write(mMac, RX_SERVICE_UUID, TX_CHAR_UUID, json.toByteArray()) { code ->
                            if (code == 0) {
                                appendColoredText("数据发送成功", TextColor.GREEN)
                            } else {
                                appendColoredText("数据发送失败: $code", TextColor.WHITE)
                            }
                        }
                } else {
                    appendColoredText("  蓝牙未连接", TextColor.RED)
                }
            }

            R.id.btnLockSetDefault -> {     // {"ResetLock":"9IxB&1234"}
                if(mConnected) {
                    data class DefaultString(val resetLock: String)

                    val str = DefaultString(userInfo.system_code.substring(0, 4) + "&1234")
                    val json = Gson().toJson(str)
                    appendColoredText("发送:" + json.replace("\\u0026", "&"), TextColor.WHITE)

                    ClientManager.getClient()
                        .write(mMac, RX_SERVICE_UUID, TX_CHAR_UUID, json.toByteArray()) { code ->
                            if (code == 0) {
                                appendColoredText("数据发送成功", TextColor.GREEN)
                            } else {
                                appendColoredText("数据发送失败: $code", TextColor.WHITE)
                            }
                        }
                } else {
                    appendColoredText("  蓝牙未连接", TextColor.RED)
                }
            }

            R.id.clearTips -> {
                clearMsg()
            }

            R.id.btnCfgOrganization -> {
                val intent = Intent(this, UserListActivity::class.java)
                intent.putExtra("title", title)  // 传递title参数
                organizationInfoLauncher.launch(intent)  // 使用新的启动方式
            }
        }
    }

    private fun appendColoredText(text: String, textType: TextColor) {
        val textString = ">$text\n"
        val spannable = SpannableString(textString)
        spannable.setSpan(
            when (textType) {  // 使用 when 表达式更简洁
                TextColor.GREEN -> ForegroundColorSpan(Color.GREEN)
                TextColor.WHITE -> ForegroundColorSpan(Color.WHITE)
                TextColor.RED -> ForegroundColorSpan(Color.RED)
            },
            0,
            textString.length,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )
        mBind.tipsTv.append(spannable)
    }

    //添加描述
    private fun clearMsg() {
        msgData = ""
        mBind.tipsTv.text = msgData
    }


    private fun showNFCDialog() {
        if (swipeDialog != null && swipeDialog!!.isShowing) {
            return
        }

        // 创建弹窗
        val builder = AlertDialog.Builder(this)
            .setTitle("请靠近NFC标签")
            .setPositiveButton("取消") { swipeDialog, _ ->
                swipeDialog?.dismiss()
                animationDrawable?.stop()
            }
        val inflater = LayoutInflater.from(this)
        val dialogView = inflater.inflate(R.layout.dialog_swipe_hint, null)
        val imageView = dialogView.findViewById<ImageView>(R.id.iv_swipe_animation)

        imageView.setBackgroundResource(R.drawable.swipe_animation)
        animationDrawable = imageView.background as AnimationDrawable

        builder.setView(dialogView)
        builder.setCancelable(true) // 点击外部可关闭
        swipeDialog = builder.create()

        // 设置弹窗显示监听器
        swipeDialog?.setOnShowListener {
            // 确保动画停止后再启动
            animationDrawable?.stop()
            animationDrawable?.start()
        }
        swipeDialog?.setOnDismissListener {
            animationDrawable?.stop()
            animationDrawable = null
        }
        swipeDialog?.show()
    }

    @SuppressLint("MissingSuperCall")
    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)

        val tag: Tag? = intent?.let {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                it.getParcelableExtra(NfcAdapter.EXTRA_TAG, Tag::class.java)
            } else {
                @Suppress("DEPRECATION")
                it.getParcelableExtra(NfcAdapter.EXTRA_TAG)
            }
        }
        val mfc = MifareUltralight.get(tag)


        var status = 0

        mfc?.connect()
        try {
            when (nfcAction) {
                is NfcAction.InitNfc -> {
                    if (tag != null && swipeDialog != null && swipeDialog!!.isShowing) {
                        val hexString = tag.id.joinToString(" ") { byte -> "%02X".format(byte) }
                        appendColoredText("【检测到的芯片】：$hexString", TextColor.GREEN)
                        ////////////////////////////////-----认证默认密码-----////////////////////////////////
                        val pack = byteArrayOf(0.toByte(), 0.toByte())
                        val auth = byteArrayOf(
                            0x1B,
                            0xFF.toByte(),
                            0xFF.toByte(),
                            0xFF.toByte(),
                            0xFF.toByte()
                        )

//                    hexString = AUTH.joinToString(" ") { byte -> "%02X".format(byte) }
//                    appendColoredText("发送：$hexString", TextColor.WHITE)

                        val response = mfc.transceive(auth)
                        if ((response != null) && (response.size >= 2)) {
                            val packResponse = Arrays.copyOf(response, 2)
                            if ((pack[0] == packResponse[0] && pack[1] == packResponse[1])) {
                                appendColoredText("【标签为出厂状态】", TextColor.WHITE)
                            }
                        }
                        ////////////////////////////////-----认证默认密码-----////////////////////////////////
                        status = 1
                        Log.e("NFC", "status= $status")
                        ////////////////////////////////-----密 码 修 改-----////////////////////////////////
                        val pageData = mfc.readPages(0) // 读取第3页
                        val ct =
                            (pageData[0] xor pageData[1] xor pageData[2] xor pageData[3])// 读不到CT值，自己计算CT值
                        val id = tag.id

                        val pwd = getUserPwd(ct, id, userInfo.system_code.substring(0, 4))
                        val modPwd = byteArrayOf(
                            0xA2.toByte(),
                            0x2B,
                            0xFF.toByte(),
                            0xFF.toByte(),
                            0xFF.toByte(),
                            0xFF.toByte()
                        )
                        pwd.copyInto(modPwd, 2, 0, 4)
//                    hexString = ModPwd.joinToString(" ") { byte -> "%02X".format(byte) }
//                    appendColoredText("发送：$hexString", TextColor.WHITE)
                        val responseModPwd = mfc.transceive(modPwd)
                        if ((responseModPwd[0] == 0x0A.toByte()) && (responseModPwd.size == 1)) {
                            appendColoredText(" 【密码修改成功】", TextColor.WHITE)
                        }
                        ////////////////////////////////-----密 码 修 改-----////////////////////////////////
                        status = 2
                        Log.e("NFC", "status= $status")
                        ////////////////////////////////-----PACK 修 改-----////////////////////////////////
                        val modPack = byteArrayOf(0xA2.toByte(), 0x2C, 0x54, 0x5A, 0, 0)
//                    hexString = ModPack.joinToString(" ") { byte -> "%02X".format(byte) }
//                    appendColoredText("发送：$hexString", TextColor.WHITE)
                        val responseModPack = mfc.transceive(modPack)
                        if ((responseModPack[0] == 0x0A.toByte()) && (responseModPack.size == 1)) {
                            appendColoredText("  【PACK修改成功】", TextColor.WHITE)
                        }
                        ////////////////////////////////-----PACK 修 改-----////////////////////////////////
                        status = 3
                        Log.e("NFC", "status= $status")
                        // 41 29H Byte[] = {0x04, 0x00, 0x00, 0x2B}
                        // |                        MIRROR【0000 0100】04H                      |  00H【保留】 |  MIRROR_PAGE【00H】  |   AUTH0【2BH】 |
                        // |【映射UID + UID从页0Ch字节1开始以ASCII代码形式映射 + 启用强调制模式】  |     保留     |     镜像页地址       |  保护起始地址  |
                        ////////////////////////////////-----Cfg1 修 改-----////////////////////////////////
//                    val ModCfg1 = byteArrayOf(0xA2.toByte(), 0x29, 0x04, 0x00, 0x00, 0x2B)
                        val modCfg1 = byteArrayOf(0xA2.toByte(), 0x29, 0x04, 0x00, 0x00, 0x04)
//                    hexString = ModCfg1.joinToString(" ") { byte -> "%02X".format(byte) }
//                    appendColoredText("发送：$hexString", TextColor.WHITE)
                        val responseModCfg1 = mfc.transceive(modCfg1)
                        if ((responseModCfg1[0] == 0x0A.toByte()) && (responseModCfg1.size == 1)) {
                            appendColoredText("   【Cfg1修改成功】", TextColor.WHITE)
                        }
                        ////////////////////////////////-----Cfg1 修 改-----////////////////////////////////
                        status = 4
                        Log.e("NFC", "status= $status")
                        // 42 2AH Byte[] = {0x00, 0x00, 0x00, 0x00}【不锁定配置页】       {0x04H, 0x00, 0x00, 0x00}【永久锁定配置页】
                        // |                  ACCESS  【0000 0 000】      【0100 0 000】                              |
                        // |写入访问受密码验证的保护 + 禁用NFC计数器 + NFC计数器未受保护 +禁用失败密码验证尝试次数限制    |
                        ////////////////////////////////-----Cfg2 修 改-----////////////////////////////////
//                    val ModCfg2 = byteArrayOf(0xA2.toByte(), 0x2A, 0x04, 0, 0, 0)
                        val modCfg2 = byteArrayOf(0xA2.toByte(), 0x2A, 0x00, 0x00, 0x00, 0x00)
//                    hexString = ModCfg2.joinToString(" ") { byte -> "%02X".format(byte) }
//                    appendColoredText("发送：$hexString", TextColor.WHITE)
                        val responseModCfg2 = mfc.transceive(modCfg2)
                        if ((responseModCfg2[0] == 0x0A.toByte()) && (responseModCfg2.size == 1)) {
                            appendColoredText("    【Cfg2修改成功】", TextColor.WHITE)
                        }
                        ////////////////////////////////-----Cfg2 修 改-----////////////////////////////////
                        mfc?.close()
                        status = 5
                        Log.e("NFC", "status= $status")
                        ////////////////////////////////-----NDEF 写 入-----////////////////////////////////
                        val ndef = Ndef.get(tag)
                        if (ndef != null) {
                            try {
                                ndef.connect()
                                val ndefMessage =
                                    NdefMessage(NdefRecord.createApplicationRecord(userInfo.name))

                                if (!ndef.isWritable) {
                                    appendColoredText("NFC标签不可写", TextColor.WHITE)
                                    return
                                }

                                try {
                                    ndef.writeNdefMessage(ndefMessage)
                                    appendColoredText("     【NDEF修改成功】", TextColor.WHITE)
                                } catch (e: Exception) {
                                    appendColoredText("NDEF写入失败: ${e.message}", TextColor.WHITE)
                                }

                            } catch (e: IOException) {
                                e.printStackTrace()
                                Log.e("NFC", "写入失败（IO异常）: ${e.message}")
                                return
                            } catch (e: FormatException) {
                                e.printStackTrace()
                                Log.e("NFC", "写入失败（格式错误）: ${e.message}")
                            } catch (e: Exception) {
                                e.printStackTrace()
                                Log.e("NFC", "写入失败（其他异常）: ${e.message}")
                                return
                            } finally {
                                try {
                                    ndef.close()
                                } catch (e: IOException) {
                                    e.printStackTrace()
                                }
                            }
                        }
                        ////////////////////////////////-----NDEF 写 入-----////////////////////////////////

                    } else {
                        Toast.makeText(this, "卡片不支持", Toast.LENGTH_SHORT).show()
                    }
                    nfcAction = null
                    swipeDialog?.dismiss()
                    animationDrawable?.stop()

                }

                is NfcAction.FormatNfc -> {
                    if (tag != null && swipeDialog != null && swipeDialog!!.isShowing) {
                        val id = tag.id
                        val hexString = id.joinToString(" ") { byte -> "%02X".format(byte) }
                        appendColoredText("【检测到的芯片】：$hexString", TextColor.GREEN)
                        ////////////////////////////////-----认证用户密码-----////////////////////////////////
                        val pageData = mfc.readPages(0) // 读取第0页
                        mfc?.close()
                        val ct =
                            (pageData[0] xor pageData[1] xor pageData[2] xor pageData[3])// 读不到CT值，自己计算CT值

                        val pwd = getUserPwd(ct, id, userInfo.system_code.substring(0, 4))
                        val pack = byteArrayOf(0x54, 0x5A)
                        val auth = byteArrayOf(
                            0x1B.toByte(),
                            0xFF.toByte(),
                            0xFF.toByte(),
                            0xFF.toByte(),
                            0xFF.toByte()
                        )
                        pwd.copyInto(auth, 1, 0, 4)
//                    hexString = pwd.joinToString(" ") { byte -> "%02X".format(byte) }
//                    appendColoredText("发送：$hexString", TextColor.WHITE)
                        mfc?.connect()
                        val response = mfc.transceive(auth)
                        if ((response != null) && (response.size == 2)) {
                            val packResponse = Arrays.copyOf(response, 2)
                            if ((pack[0] == packResponse[0] && pack[1] == packResponse[1])) {
                                appendColoredText("【标签已初始化】", TextColor.WHITE)
                            }
                        }
                        ////////////////////////////////-----认证用户密码-----////////////////////////////////
                        status = 1
                        Log.e("NFC", "status= $status")
                        ////////// ////////////////////-----密码修改为默认值-----/////////////////////////////
                        val modPwd = byteArrayOf(
                            0xA2.toByte(),
                            0x2B,
                            0xFF.toByte(),
                            0xFF.toByte(),
                            0xFF.toByte(),
                            0xFF.toByte()
                        )
//                    hexString = ModPwd.joinToString(" ") { byte -> "%02X".format(byte) }
//                    appendColoredText("发送：$hexString", TextColor.WHITE)
                        val responseModPwd = mfc.transceive(modPwd)
                        if ((responseModPwd[0] == 0x0A.toByte()) && (responseModPwd.size == 1)) {
                            appendColoredText(" 【密码修改成功】", TextColor.WHITE)
                        }
                        ////////// ////////////////////-----密码修改为默认值-----/////////////////////////////
                        status = 2
                        Log.e("NFC", "status= $status")
                        ////////////////////////////////-----PACK 修 改-----////////////////////////////////
                        val modPack = byteArrayOf(0xA2.toByte(), 0x2C, 0, 0, 0, 0)
//                    hexString = ModPack.joinToString(" ") { byte -> "%02X".format(byte) }
//                    appendColoredText("发送：$hexString", TextColor.WHITE)
                        val responseModPack = mfc.transceive(modPack)
                        if ((responseModPack[0] == 0x0A.toByte()) && (responseModPack.size == 1)) {
                            appendColoredText("  【PACK修改成功】", TextColor.WHITE)
                        }
                        ////////////////////////////////-----PACK 修 改-----////////////////////////////////
                        status = 3
                        Log.e("NFC", "status= $status")
                        // 41 29H Byte[] = {0x04, 0x00, 0x00, 0xFF}
                        // |                        MIRROR【0000 0100】04H                      |  00H【保留】 |  MIRROR_PAGE【00H】  |   AUTH0【2BH】 |
                        // |【映射UID + UID从页0Ch字节1开始以ASCII代码形式映射 + 启用强调制模式】  |     保留     |     镜像页地址       |  保护起始地址  |
                        ////////////////////////////////-----Cfg1 修 改-----////////////////////////////////
                        val modCfg1 =
                            byteArrayOf(0xA2.toByte(), 0x29, 0x04, 0x00, 0x00, 0xFF.toByte())
//                    hexString = ModCfg1.joinToString(" ") { byte -> "%02X".format(byte) }
//                    appendColoredText("发送：$hexString", TextColor.WHITE)
                        val responseModCfg1 = mfc.transceive(modCfg1)
                        if ((responseModCfg1[0] == 0x0A.toByte()) && (responseModCfg1.size == 1)) {
                            appendColoredText("   【Cfg1修改成功】", TextColor.WHITE)
                        }
                        ////////////////////////////////-----Cfg1 修 改-----////////////////////////////////
                        status = 4
                        Log.e("NFC", "status= $status")
                        // 42 2AH Byte[] = {0x00, 0x00, 0x00, 0x00}【不锁定配置页】       {0x04H, 0x00, 0x00, 0x00}【永久锁定配置页】
                        // |                  ACCESS  【0000 0 000】      【0100 0 000】                              |
                        // |写入访问受密码验证的保护 + 禁用NFC计数器 + NFC计数器未受保护 +禁用失败密码验证尝试次数限制    |
                        ////////////////////////////////-----Cfg2 修 改-----////////////////////////////////
//                    val ModCfg2 = byteArrayOf(0xA2.toByte(), 0x2A, 0x04, 0, 0, 0)
                        val modCfg2 = byteArrayOf(0xA2.toByte(), 0x2A, 0x00, 0x00, 0x00, 0x00)
//                    hexString = ModCfg2.joinToString(" ") { byte -> "%02X".format(byte) }
//                    appendColoredText("发送：$hexString", TextColor.WHITE)
                        val responseModCfg2 = mfc.transceive(modCfg2)
                        if ((responseModCfg2[0] == 0x0A.toByte()) && (responseModCfg2.size == 1)) {
                            appendColoredText("    【Cfg2修改成功】", TextColor.WHITE)
                        }
                        ////////////////////////////////-----Cfg2 修 改-----////////////////////////////////
                        val resetData = byteArrayOf(
                            0xA2.toByte(),
                            0x00,
                            0x00,
                            0x00,
                            0x00,
                            0x00
                        )
                        val page4 = byteArrayOf(0x01, 0x03, 0xA0.toByte(), 0x0C)
                        val page5 = byteArrayOf(0x34, 0x03, 0x00, 0xFE.toByte())
                        val page6to39 = byteArrayOf(0x00, 0x00, 0x00, 0x00)
                        for (block in 4..39) {
                            resetData[1] = block.toByte()
                            when (block) {
                                4 -> page4.copyInto(resetData, 2, 0, 4)
                                5 -> page5.copyInto(resetData, 2, 0, 4)
                                else -> page6to39.copyInto(resetData, 2, 0, 4)
                            }
                            mfc.transceive(resetData)
                        }
                        appendColoredText("     【清除NDEF成功】Page4-Page39", TextColor.WHITE)

                        ////////////////////////////////-----NDEF 写 入-----////////////////////////////////
                    } else {
                        Toast.makeText(this, "卡片不支持", Toast.LENGTH_SHORT).show()
                    }
                    nfcAction = null
                    swipeDialog?.dismiss()
                    animationDrawable?.stop()
                    return
                }

                null -> {
                    if (tag != null) {
                        val hexString = tag.id.joinToString(" ") { byte -> "%02X".format(byte) }
                        appendColoredText("【检测到的芯片】：$hexString", TextColor.GREEN)

                        var retryCount = 0
                        while (retryCount < 2) {
                            try {
                                if (retryCount == 0) {
                                    ////////////////////////////////-----认证默认密码-----////////////////////////////////
                                    val pack = byteArrayOf(0.toByte(), 0.toByte())
                                    val auth = byteArrayOf(
                                        0x1B,
                                        0xFF.toByte(),
                                        0xFF.toByte(),
                                        0xFF.toByte(),
                                        0xFF.toByte()
                                    )
//                                hexString = AUTH.joinToString(" ") { byte -> "%02X".format(byte) }
//                                appendColoredText("发送：$hexString", TextColor.WHITE)

                                    val response = mfc.transceive(auth)
                                    if ((response != null) && (response.size == 2)) {
                                        val packResponse = Arrays.copyOf(response, 2)
                                        if ((pack[0] == packResponse[0] && pack[1] == packResponse[1])) {
                                            appendColoredText("【标签为出厂状态】", TextColor.WHITE)
                                        }
                                    }
                                    retryCount = 0xFF
                                    ////////////////////////////////-----认证默认密码-----////////////////////////////////
                                } else if (retryCount == 1) {
                                    mfc?.connect()
                                    ////////////////////////////////-----认证用户密码-----////////////////////////////////
                                    val pageData = mfc.readPages(0) // 读取第3页
                                    val ct =
                                        (pageData[0] xor pageData[1] xor pageData[2] xor pageData[3])// 读不到CT值，自己计算CT值
                                    val id = tag.id

                                    val pwd =
                                        getUserPwd(ct, id, userInfo.system_code.substring(0, 4))
                                    val pack = byteArrayOf(0x54, 0x5A)
                                    val auth = byteArrayOf(
                                        0x1B.toByte(),
                                        0xFF.toByte(),
                                        0xFF.toByte(),
                                        0xFF.toByte(),
                                        0xFF.toByte()
                                    )
                                    pwd.copyInto(auth, 1, 0, 4)
//                                hexString = pwd.joinToString(" ") { byte -> "%02X".format(byte) }
//                                appendColoredText("发送：$hexString", TextColor.WHITE)
                                    val response = mfc.transceive(auth)
                                    if ((response != null) && (response.size == 2)) {
                                        val packResponse = Arrays.copyOf(response, 2)
                                        if ((pack[0] == packResponse[0] && pack[1] == packResponse[1])) {
                                            appendColoredText("【标签已初始化】", TextColor.WHITE)
                                        }
                                    }
                                    ////////////////////////////////-----认证用户密码-----////////////////////////////////

                                    ////////////////////////////////------读机构信息------////////////////////////////////
                                    mfc?.close()
                                    val ndef = Ndef.get(tag)
                                    if (ndef != null) {

                                        try {
                                            ndef.connect()
                                            val ndefMessage =
                                                ndef.ndefMessage          // 获取 NDEF 消息
                                            if (ndefMessage != null) {
                                                for (record in ndefMessage.records) {   // 获取所有 NDEF 记录
                                                    when (record.tnf) { // TNF（Type Name Format）判断数据类型
                                                        NdefRecord.TNF_WELL_KNOWN -> {
                                                            val text = String(
                                                                record.payload,
                                                                Charsets.UTF_8
                                                            ) // 这是标准文本数据
                                                            appendColoredText(
                                                                " 【${text}】",
                                                                TextColor.WHITE
                                                            )
                                                        }

                                                        NdefRecord.TNF_EXTERNAL_TYPE -> {
                                                            val text = String(
                                                                record.payload,
                                                                Charsets.UTF_8
                                                            ) // 这是自定义文本数据
                                                            appendColoredText(
                                                                " 【${text}】",
                                                                TextColor.WHITE
                                                            )
                                                        }

                                                        else -> appendColoredText(
                                                            " 【\"非法 NDEF 类型: ${record.tnf}\"】",
                                                            TextColor.WHITE
                                                        )
                                                    }
                                                }
                                            } else {
                                                Log.d("NFC", "标签为空")
                                            }
                                        } catch (e: IOException) {
                                            Log.e("NFC", "读取失败（IO异常）: ${e.message}")
                                        } catch (e: FormatException) {
                                            Log.e("NFC", "读取失败（格式错误）: ${e.message}")
                                        } finally {
                                            try {
                                                ndef.close()
                                            } catch (e: IOException) {
                                                Log.e("NFC", "关闭连接失败: ${e.message}")
                                            }
                                        }
                                    }
                                    ////////////////////////////////------读机构信息------////////////////////////////////
                                    retryCount = 0xFF
                                }
                            } catch (e: TagLostException) {
                                mfc?.close()
                                e.printStackTrace()
                                retryCount++
                            }
                        }
                    }
                }
            }
        } catch (e: TagLostException) {
            e.printStackTrace()
            if (swipeDialog != null && swipeDialog!!.isShowing) {
                when (nfcAction) {
                    is NfcAction.InitNfc -> {
                        when (status) {
                            0 -> appendColoredText("【标签认证失败】", TextColor.WHITE)
                            1 -> appendColoredText("【密码修改失败】", TextColor.WHITE)
                            2 -> appendColoredText("【PACK修改失败】", TextColor.WHITE)
                            3 -> appendColoredText("【Cfg1修改失败】", TextColor.WHITE)
                            4 -> appendColoredText("【Cfg2修改失败】", TextColor.WHITE)
                            5 -> appendColoredText("【NDEF修改失败】", TextColor.WHITE)
                        }
                        nfcAction = null
                    }

                    is NfcAction.FormatNfc -> {
                        when (status) {
                            0 -> appendColoredText("【标签认证失败】", TextColor.WHITE)
                            1 -> appendColoredText("【密码恢复失败】", TextColor.WHITE)
                            2 -> appendColoredText("【PACK恢复失败】", TextColor.WHITE)
                            3 -> appendColoredText("【Cfg1修改失败】", TextColor.WHITE)
                            4 -> appendColoredText("【Cfg2修改失败】", TextColor.WHITE)
                            5 -> appendColoredText("【NDEF清除失败】", TextColor.WHITE)
                        }
                        nfcAction = null
                    }

                    null -> {
                        // 处理未设置状态
                        println("NFC动作未设置")
                    }
                }
                swipeDialog?.dismiss()
                animationDrawable?.stop()
            }
        } catch (e: IOException) {
            e.printStackTrace()
            if (swipeDialog != null && swipeDialog!!.isShowing) {
                swipeDialog?.dismiss()
                animationDrawable?.stop()
            }
            Toast.makeText(this, "读取失败！", Toast.LENGTH_SHORT).show()
        } finally {
            mfc?.close()
        }
    }

    private fun transformByteWithFactor(index: Int, input: Byte, factor: Int): Byte {
        // 示例算法：将输入字节与因子相乘，然后与0x5A异或
        var result = (input.toInt() and 0xFF) * factor
        result = (result xor (if (index % 2 == 0) 0x5A else 0xA5)) and 0xFF
        return result.toByte()
    }

    private fun getUserPwd(ct: Byte, id: ByteArray, sysCodeStr: String): ByteArray {
        val uid = ByteArray(16) { 0.toByte() } // 初始化为 0
        var sysCode = ByteArray(4)
//        if (userInfo.name == "点位挂牌锁出厂测试" && userInfo.system_code == "12345678") {
        if (userInfo.system_code == "12345678") {
            sysCode[0] = 0x01.toByte()
            sysCode[1] = 0x02.toByte()
            sysCode[2] = 0x03.toByte()
            sysCode[3] = 0x04.toByte()
        } else {
            sysCode = sysCodeStr.toByteArray()
        }
        uid[0] = ct
        id.copyInto(uid, 1, 0, id.size)
        uid[15] = (0xA0.toByte() + 7).toByte()
        val pwd = ByteArray(4) { 0.toByte() } // 初始化为 0
        for (i in 0..3) {
            pwd[i] = transformByteWithFactor(i, sysCode[i], uid[1 + i].toInt())
        }
        return pwd
    }

//    //创建一个封装要写入的文本的NdefRecord对象
//    private fun createTextRecord(text: String): NdefRecord {
//
//        val langBytes = Locale.CHINA.language.toByteArray(
//            Charset.forName("US-ASCII")
//        );
//        //将要写入的文本以UTF_8格式进行编码
//        val utfEncoding = Charset.forName("UTF-8");
//        //因为已经确定文本的格式编码为UTF_8。所以直接将payload的第1个字节的第7位设为0
//        val textBytes = text.toByteArray(utfEncoding);
//        val utfBit = 0;
//        //定义和初始化状态字节
//        val status = (utfBit + langBytes.size).toChar();
//        //创建存储payload的字节数组
//        val data = ByteArray(1 + langBytes.size + textBytes.size);
//        //设置状态字节
//        data[0] = status.toByte()
//        //设置语言编码
//        System.arraycopy(langBytes, 0, data, 1, langBytes.size);
//        //设置实际要写入的文本
//        System.arraycopy(
//            textBytes, 0, data, 1 + langBytes.size,
//            textBytes.size
//        );
//        //依据前面设置的payload创建NdefRecord对象
//        val record = NdefRecord(
//            NdefRecord.TNF_WELL_KNOWN,
//            NdefRecord.RTD_TEXT, ByteArray(0), data
//        );
//        return record;
//
//    }

    override fun onResume() {
        super.onResume()
        // 设置当该页面处于前台时，NFC标签会直接交给该页面处理
//        mNfcAdapter?.enableForegroundDispatch(this, mPendingIntent, null, null);

        val nfcAdapter = NfcAdapter.getDefaultAdapter(this)
        val pendingIntent = PendingIntent.getActivity(
            this, 0, Intent(this, javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                PendingIntent.FLAG_MUTABLE
            } else {
                0
            }
        )
        nfcAdapter?.enableForegroundDispatch(this, pendingIntent, null, null)

    }

    override fun onPause() {
        super.onPause()
        // 当页面不可见时，NFC标签不交给当前页面处理
        mNfcAdapter?.disableForegroundDispatch(this)
    }


    /**
     * 照相机权限
     */
    /*
    private val disposable = CompositeDisposable()

    private fun checkPermissions() {
        val rxPermissions = RxPermissions(this)

        val permissionDisposable = rxPermissions
            .request(Manifest.permission.CAMERA)
            .subscribe { granted: Boolean ->
                if (granted) {
                    appendColoredText("权限已授予", TextColor.WHITE)
                } else {
                    appendColoredText("权限被拒绝", TextColor.WHITE)
                }
            }

        disposable.add(permissionDisposable)
    }

    override fun onDestroy() {
        super.onDestroy()
        disposable.clear() // 清理所有订阅，防止内存泄漏
    }
    */
    override fun onDestroy() {
        super.onDestroy()
        // 关闭弹窗并停止动画，防止内存泄漏
        swipeDialog?.dismiss()
        animationDrawable?.stop()

        mMac?.let {
            ClientManager.getClient().disconnect(mMac)
            ClientManager.getClient()
                .unregisterConnectStatusListener(mMac, mBleConnectStatusListener)

            appendColoredText("蓝牙连接断开", TextColor.RED)
            mConnected = false
        }
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.main_menu, menu)
        return super.onCreateOptionsMenu(menu)
    }

    object SharedPreferencesUtils {
        fun saveUserInfo(context: Context, name: String, systemCode: String) {
            val prefs = context.getSharedPreferences("UserInfoPrefs", Context.MODE_PRIVATE)
            prefs.edit()
                .putString("user_name", name)
                .putString("system_code", systemCode)
                .apply()
        }

        fun loadUserInfo(context: Context): UserInfo {
            val prefs = context.getSharedPreferences("UserInfoPrefs", Context.MODE_PRIVATE)
            return UserInfo(
                name = prefs.getString("user_name", "") ?: "",
                system_code = prefs.getString("system_code", "") ?: ""
            )
        }
    }

    override fun onPrepareOptionsMenu(menu: Menu): Boolean {
        val settingItem = menu.findItem(R.id.menu_setting)
        settingItem.setIcon(
            if (mConnected) {
                R.drawable.ic_bluetooth_connected_black_24dp
            } else {
                R.drawable.ic_bluetooth_black_24dp
            }
        )
        if (mConnected) {
            mBind.btnLockInit.setBackgroundColor(ContextCompat.getColor(this, R.color.buttonReleased))
            mBind.btnLockSetDefault.setBackgroundColor(ContextCompat.getColor(this, R.color.buttonReleased))
        } else {
            mBind.btnLockInit.setBackgroundColor(ContextCompat.getColor(this, R.color.buttonPressed))
            mBind.btnLockSetDefault.setBackgroundColor(ContextCompat.getColor(this, R.color.buttonPressed))
        }
        return super.onPrepareOptionsMenu(menu)
    }

    // 当连接状态改变时调用此方法
    private fun updateBluetoothIcon() {
        invalidateOptionsMenu() // 这会触发onPrepareOptionsMenu重新执行
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.menu_setting -> {
                if(mConnected){
                    mMac?.let {
                        ClientManager.getClient().disconnect(mMac)
                        ClientManager.getClient()
                            .unregisterConnectStatusListener(mMac, mBleConnectStatusListener)

                        appendColoredText("蓝牙连接断开", TextColor.RED)
                        mConnected = false
                        updateBluetoothIcon()
                    }
                }

                val bundle = Bundle()
                bundle.putInt("deviceType", 2)
                toStartActivity(DeviceListActivity::class.java, bundle)
            }
        }
        return super.onOptionsItemSelected(item)
    }

}
